﻿using System;
using System.Linq;
using System.Collections.Generic;
using MersenneTwister;

namespace Gamemaster
{
    public static class Roll
    {
        private static readonly MT19937 mt = new MT19937();

        public static int d(int sides)
        {
            if (sides < 2)
            {
                throw new ArgumentException("Attempted to roll a die with less than two sides.");
            }

            return mt.RandomRange(1, sides);
        }
        public static int d100()
        {
            return d(100);
        }
        public static int d20()
        {
            return d(20);
        }
        public static int d12()
        {
            return d(12);
        }
        public static int d10()
        {
            return d(10);
        }
        public static int d8()
        {
            return d(8);
        }
        public static int d6()
        {
            return d(6);
        }
        public static int d4()
        {
            return d(4);
        }

        /// <summary>
        /// Adds a bonus to the specified roll value. Negative bonus values will
        /// subtract from the roll value.
        /// </summary>
        /// <remarks>
        /// Minimum value returned by this method is zero.
        /// </remarks>
        public static int Plus(this int roll, int bonus)
        {
            return Math.Max(0, roll + bonus);
        }
        /// <summary>
        /// Subtracts a penalty from the specified roll value. The absolute value
        /// of the penalty is used so that negative penalty values are still subtracted
        /// from the roll value.
        /// </summary>
        /// <remarks>
        /// Minimum value returned by this method is zero.
        /// </remarks>
        public static int Minus(this int roll, int penalty)
        {           
            return Math.Max(0, roll - Math.Abs(penalty));
        }
        /// <summary>
        /// Roll a die 'n' times and return the results, where 'n' is the integer
        /// calling this method.
        /// </summary>
        public static RollResults d(this int numberOfDice, int sides)
        {
            return new RollResults(numberOfDice, sides);
        }
        /// <summary>
        /// Formats the specified bonus modifier for display.
        /// </summary>
        public static string ToBonusString(this int modifier)
        {
            if (modifier != 0)
            {
                string operation = modifier > 0 ? "+" : "-";

                return string.Concat(operation, Math.Abs(modifier));
            }
            else
            {
                return string.Empty;
            }
        }        
        /// <summary>
        /// Formats the specified penalty modifier for display.
        /// </summary>
        public static string ToPenaltyString(this int modifier)
        {
            if (modifier != 0)
            {
                return string.Concat("-", Math.Abs(modifier));
            }
            else
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// Formats the list of integers for display.
        /// </summary>
        public static string ToResultsString(this IEnumerable<int> results)
        {
            string[] converted = results.Cast<string>().ToArray();

            return string.Concat("[ ", string.Join(",", converted), " ]");
        }
    }
}
